/*
 * ============================================================================
 *
 *       Filename:  message.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2014年08月26日 09时16分29秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  jianxi sun (jianxi), ycsunjane@gmail.com
 *   Organization:  
 *
 * ============================================================================
 */
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>

#include "thread.h"
#include "message.h"
#include "process.h"
#include "sockarr.h"
#include "arg.h"
#include "log.h"

LIST_HEAD(head);
INIT_LOCK(msglock);

void message_insert(struct message_t *msg)
{
	sys_debug("message insert msg: %p\n", msg);

	LOCK(&msglock);
	list_add_tail(&msg->list, &head);
	UNLOCK(&msglock);
}

static struct message_t * message_delete()
{
	struct message_t *msg;

	LOCK(&msglock);
	if(list_empty(&head)) {
		UNLOCK(&msglock);
		return NULL;
	}
	
	msg = container_of(head.next, struct message_t, list);
	list_del(&msg->list);
	UNLOCK(&msglock);

	sys_debug("message delete: %p\n", msg);
	return msg;
}

static void message_free(struct message_t *msg)
{
	switch(msg->proto) {
	case MSG_PROTO_TCP:
		free(msg->data);
	case MSG_PROTO_ETH:
		free(msg);
		break;
	default:
		sys_err("error msg proto\n");
		exit(-1);
	}
}

void *message_travel(void *arg)
{
	struct message_t *msg;

	while(1) {
		sleep(args_info.msgitv_arg);

		while((msg = message_delete())) {
			pr_pkt(msg->data, msg->len);
			msg_proc((void *)msg->data, 
				msg->len, msg->proto);
			message_free(msg);
		}
		sys_debug("Message travel pthreads "
			"(next %d second later)\n", 
			args_info.msgitv_arg);
	}
	return NULL;
}

void message_init()
{
	pthread_create_detach(message_travel, NULL);
	sys_info("MODULE: message travel init success\n");
}
